package com.beiding.jsonanalyzer;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.beiding.jsonanalyzer.analyze.*;
import com.beiding.jsonanalyzer.flow.*;
import com.beiding.jsonanalyzer.flow.branchevents.FlowEnd;
import com.beiding.jsonanalyzer.flow.branchevents.StopNow;
import com.beiding.jsonanalyzer.flow.flowevents.*;
import com.beiding.jsonanalyzer.querylink.QueryLinkNode;
import com.beiding.jsonanalyzer.querylink.QueryLinkNodeResult;

import java.util.*;
import java.util.Comparator;


/**
 * 1. 抽取抽象算法,simpleVisit ,deep,deepWithTime
 * <p>
 * 2. 深度键赋值
 * <p>
 * 3. 深度键取值
 * <p>
 * 4. 两个json比对,键比对和值比对两种
 * <p>
 * 5. 模式提取:
 * 值节点分组:有多个值相同的叶子节点
 * 模式:
 * <p>
 * 节点本身不持有content,因为本地非json节点的content感知不到source节点上内容的变更
 */
public class Analyzer {

    /**
     * 使用create方法创建时的源对象
     */
    private Object source;


    /**
     * 绝对key
     */
//    protected Key absoluteKey;

    /**
     * 相对from的key
     */
//    protected Key relativeKey;

/*

    public Key getRelativeKey() {
        return relativeKey;
    }

    public Key getAbsoluteKey() {
        return absoluteKey;
    }

    public boolean isRelative() {
        return getRelativeKey().equals(getAbsoluteKey());
    }
*/

    //========构建=========
    public Analyzer() {
/*        this.relativeKey = new Key();
        this.absoluteKey = new Key();*/
        this.source = JSON.toJSON(new HashMap<>());
    }


    /**
     * 创建一个实例
     *
     * @param object
     * @return
     */
    public Analyzer(Object object) {
        this.source = object;

        //相对获取者的节点
        /*this.relativeKey = new Key();
        this.absoluteKey = new Key();*/
    }

    public static Analyzer parse(String text) {
        return new Analyzer(JSON.parse(text));
    }

    public static Analyzer load(Object input) {
        return parse(ResourceUtils.read(input));
    }

    //=========删除自身=======

  /*  public void delete() {
        remove(source, absoluteKey);
    }*/

    //============展示=============

    public void writeTo(Object output) {
        ResourceUtils.write(toString(), output);
    }

    public void formatWriteTo(Object output, String tab) {
        ResourceUtils.write(format(tab), output);
    }

    public void formatWriteTo(Object output) {
        ResourceUtils.write(format(), output);
    }


    //===========内容赋值取值============

    /**
     * 设置源
     *
     * @param content
     */
    public void setSource(Object content) {
        /*if (from == null) {//根节点

            this.source = content;
        } else {
            this.from.insertNext(this.relativeKey, content);
        }*/
//        set(source, this.absoluteKey, content);
//        set(source, new Key(), content);

        this.source = content;

    }


//    public Object getSource() {
//        return getSource(Object.class);
//    }
//
//    public <T> T as(Class<T> type) {
//        return getSource(type);
//    }
//
//    public <T> T getSource(Class<T> type) {
//    /*    if (from == null) {
//            return (T) source;
//        } else {//相对坐标*/
//        return get(this.source, this.absoluteKey, type);
//        // }
//    }

    //=====类型判断======

  /*  public boolean isJsonArray() {
        return getSource() instanceof JSONArray;
    }

    public boolean isJsonObject() {
        return getSource() instanceof JSONObject;
    }

    public boolean isNull() {
        return getSource() == null;
    }

    public ContentType getSourceType() {
        if (isJsonArray()) {
            return ContentType.ARRAY;
        } else if (isJsonObject()) {
            return ContentType.OBJECT;
        } else {
            return ContentType.OTHER;
        }
    }*/

    //=======array=======
    public int size() {
        Object content = source;
        if (content instanceof JSONArray) {
            return ((JSONArray) content).size();
        } else if (content instanceof JSONObject) {
            return ((JSONObject) content).size();
        } else {
            return 0;
        }
    }

    //=============内容强转=============

//    public String stringContent() {
//        return getSource(String.class);
//    }
//
//    public Integer intContent() {
//        return getSource(Integer.class);
//    }
//
//    public Long longContent() {
//        return getSource(Long.class);
//    }
//
//    public Short shortContent() {
//        return getSource(Short.class);
//    }
//
//    public Boolean booleanContent() {
//        return getSource(Boolean.class);
//    }
//
//    public Byte byteContent() {
//        return getSource(Byte.class);
//    }
//
//    public Double doubleContent() {
//        return getSource(Double.class);
//    }
//
//    public Float floatContent() {
//        return getSource(Float.class);
//    }
//
//    public Character charContent() {
//        return getSource(Character.class);
//    }

//    public JSONObject jsonObjectContent() {
//        return getSource(JSONObject.class);
//    }
//
//    public JSONArray jsonArrayContent() {
//        return getSource(JSONArray.class);
//    }

    //======是否具有这个键======
    public static boolean hasKey(Object obj, Object keyV) {


        keyV = KeyUtils.handleKey(keyV, KeyMode.TEXT_TO_KEY);

        if (!(keyV instanceof Key)) {
            return false;
        }

        Key key = (Key) keyV;

        List<Segment> list = key.getSegments();
        if (list.size() > 0) {

            //类型不匹配
            if (!(obj instanceof JSON)) {
                return false;
            }

            //父级对象
            Object p = obj;

            int lastSeg = list.size() - 1;

            //获取最后一段之前的节点,然后获取最后一段的值
            for (int i = 0; i < lastSeg; i++) {

                Segment segment = list.get(i);

                if (segment.type == SegmentType.NAME) {

                    String name = segment.name;

                    //如果父节点不存在. 初始化一个父节点的元素
                    if (p == null) {
                        return false;
                    } else if (!(p instanceof JSONObject)) {
                        //检查是否是期望的类型
                        return false;
                    }

                    JSONObject z = (JSONObject) p;

                    //获取一下当前节点
                    p = z.get(name);

                } else if (segment.type == SegmentType.INDEX) {

                    int index = segment.index;

                    //如果父节点不存在. 初始化一个父节点的元素
                    if (p == null) {
                        return false;
                    } else if (!(p instanceof JSONArray)) {
                        //检查是否是期望的类型
                        return false;

                    }

                    JSONArray z = (JSONArray) p;

                    if (z.size() <= index) {
                        return false;
                    }

                    //获取一下当前节点
                    p = z.get(index);
                } else {
                    return false;
                }
            }

            Segment segment = list.get(lastSeg);

            if (segment.type == SegmentType.NAME) {
                String name = segment.name;
                if (p == null) {
                    return false;
                } else if (!(p instanceof JSONObject)) {
                    //检查是否是期望的类型
                    return false;
                }

                JSONObject z = (JSONObject) p;

                return z.containsKey(name);

            } else if (segment.type == SegmentType.INDEX) {
                int index = segment.index;

                if (p == null) {
                    return false;
                } else if (!(p instanceof JSONArray)) {
                    //检查是否是期望的类型
                    return false;
                }
                JSONArray z = (JSONArray) p;


                if (z.size() <= index) {
                    return false;
                }

                return true;

            } else {
                return false;
            }


        } else {
            return true;
        }


    }

    public boolean hasKey(Object key) {
        return hasKey(getSource(), key);
    }

    //=======取值======

    /**
     * 从一个对象中获取值
     *
     * @param obj
     * @param keyV
     * @param type
     * @param <T>
     * @return
     */
    public static <T> T get(Object obj, Object keyV, Class<T> type) {

        if (keyV instanceof String) {
            if (obj instanceof JSONObject) {
                return ((JSONObject) obj).getObject((String) keyV, type);
            } else {
                throw new UnsupportedOperationException("不支持使用字符串对非JSON对象获取值");
            }
        }

        keyV = KeyUtils.handleKey(keyV, KeyMode.TEXT_TO_KEY);

        if (keyV == null) {
            keyV = new Key();
        }

        if (!(keyV instanceof Key)) {
            throw new IllegalArgumentException("不支持该对象为Key" + keyV);
        }

        Key key = (Key) keyV;

        List<Segment> list = key.getSegments();
        if (list.size() > 0) {

            //类型不匹配
            if (!(obj instanceof JSON)) {
                throw new UnsupportedOperationException("不支持非JSON对象获取值");
            }

            //父级对象
            Object p = obj;

            int lastSeg = list.size() - 1;

            //获取最后一段之前的节点,然后获取最后一段的值
            for (int i = 0; i < lastSeg; i++) {

                Segment segment = list.get(i);

                if (segment.type == SegmentType.NAME) {

                    String name = segment.name;

                    //如果父节点不存在. 初始化一个父节点的元素
                    if (p == null) {
                        return null;
                    } else if (!(p instanceof JSONObject)) {
                        //检查是否是期望的类型
                        throw new UnsupportedOperationException("期望JSONObject,当前节点不支持取值操作:" + key.subKey(0, i));
                    }

                    JSONObject z = (JSONObject) p;

                    //获取一下当前节点
                    p = z.get(name);

                } else if (segment.type == SegmentType.INDEX) {

                    int index = segment.index;

                    //如果父节点不存在. 初始化一个父节点的元素
                    if (p == null) {
                        return null;
                    } else if (!(p instanceof JSONArray)) {
                        //检查是否是期望的类型
                        throw new UnsupportedOperationException("期望JSONArray,当前节点不支持取值操作:" + key.subKey(0, i));
                    }

                    JSONArray z = (JSONArray) p;

                    //数组越界问题不处理

                    //获取一下当前节点
                    p = z.get(index);
                } else {
                    throw new UnsupportedOperationException("暂时不支持的分段类型:" + segment.type);
                }
            }

            Segment segment = list.get(lastSeg);

            if (segment.type == SegmentType.NAME) {
                String name = segment.name;
                if (p == null) {
                    return null;
                } else if (!(p instanceof JSONObject)) {
                    //检查是否是期望的类型
                    throw new UnsupportedOperationException("期望JSONObject,当前节点不支持取值操作:" + key);
                }
                JSONObject z = (JSONObject) p;

                return z.getObject(name, type);

            } else if (segment.type == SegmentType.INDEX) {
                int index = segment.index;

                if (p == null) {
                    return null;
                } else if (!(p instanceof JSONArray)) {
                    //检查是否是期望的类型
                    throw new UnsupportedOperationException("期望JSONArray,当前节点不支持取值操作:" + key);
                }
                JSONArray z = (JSONArray) p;
                return z.getObject(index, type);

            } else {
                throw new UnsupportedOperationException("暂时不支持的分段类型:" + segment.type);
            }


        } else {

            if (type == null || obj == null) {

                return null;
            }

            if (type.isInstance(obj)) {
                return (T) obj;
            }

            throw new ClassCastException(obj.getClass().getName() + " cannot be cast to " + type.getName());
        }

    }

    public Object get(Object key) {
        return get(key, Object.class);
    }

    public <T> T get(Object key, Class<T> type) {
        return get(getSource(), key, type);
    }


    public String getString(Object key) {
        return get(key, String.class);
    }

    public Integer getInt(Object key) {
        return get(key, Integer.class);
    }

    public Long getLong(Object key) {
        return get(key, Long.class);
    }

    public Short getShort(Object key) {
        return get(key, Short.class);
    }

    public Boolean getBoolean(Object key) {
        return get(key, Boolean.class);
    }

    public Byte getByte(Object key) {
        return get(key, Byte.class);
    }

    public Double getDouble(Object key) {
        return get(key, Double.class);
    }

    public Float getFloat(Object key) {
        return get(key, Float.class);
    }

    public Character getChar(Object key) {
        return get(key, Character.class);
    }

    public JSONObject getJsonObject(Object key) {
        return get(key, JSONObject.class);
    }

    public JSONArray getJsonArray(Object key) {
        return get(key, JSONArray.class);
    }


    //==========特殊获取===============
/*    public Analyzer getAnalyzer(Object key) {
        Key k;
        if (key instanceof Key) {
            k = (Key) key;
        } else if (key instanceof Number) {
            Number number = (Number) key;
            k = new Key(number.intValue());
        } else if (key == null) {
            return null;
        } else {
            k = Key.read(key.toString());
        }

        Key absKey = this.absoluteKey.concat(k);

        Object o = get(this.source, absKey, Object.class);

        //TODO 如果是undefined返回null,如果本身是有null占位的则返回分析对象
        if (o == null) {//如果给定的key不存在就直接返回null
            return null;
        }

        Analyzer analyzer = new Analyzer();
        //  analyzer.from = this;
        analyzer.source = this.source;
        analyzer.absoluteKey = absKey;
        analyzer.relativeKey = k;
        return analyzer;
    }

    public Analyzer getParentAnalyzer() {
        Analyzer analyzer = new Analyzer();
        analyzer.source = this.source;
        analyzer.absoluteKey = this.absoluteKey.parentKey();
        //      analyzer.from = this;
        analyzer.relativeKey = Key.PARENT_KEY;
        return analyzer;
    }*/

/*
    public List<Analyzer> listChildren() {
        List<Analyzer> analyzers = new ArrayList<>();
        List<Key> keys = keysWithLength(1);
        for (Key key : keys) {
            analyzers.addElement(getAnalyzer(key));
        }
        return analyzers;
    }*/

    /**
     * 只复制自身
     *
     * @return
     */
  /*  public Analyzer selfCopy() {
        return createInstance(JSON.read(getSource().toString()));
    }
*/

    /**
     * 全路径复制,即从自身相对的跟节点复制,然后获取一个子节点
     *
     * @return
     */
 /*   public Analyzer fullCopy() {
        return createInstance(JSON.read(this.source.toString())).getAnalyzer(this.absoluteKey);
    }*/

  /*  public void clearNull() {
        if (isJsonArray()) {
            jsonArrayContent().removeIf(Objects::isNull);
        }
    }*/


    //======赋值======

    private interface ValueSetter {

        void changeValue(Object value);

        Object remove();
    }

    private static class ArraySetter implements Analyzer.ValueSetter {

        int index;

        JSONArray parent;

        ArraySetter(JSONArray parent, int index) {
            this.parent = parent;
            this.index = index;
        }

        @Override
        public void changeValue(Object value) {

            parent.set(index, value);

        }

        @Override
        public Object remove() {
            return parent.remove(index);
        }
    }


    private static class ObjectSetter implements Analyzer.ValueSetter {

        String name;

        JSONObject parent;

        ObjectSetter(JSONObject parent, String name) {
            this.parent = parent;
            this.name = name;
        }

        @Override
        public void changeValue(Object value) {
            parent.put(name, value);
        }

        @Override
        public Object remove() {
            return parent.remove(name);
        }

    }

    public static void set(Object obj, Object kz, Object value) {

        Object handleKey = KeyUtils.handleKey(kz, KeyMode.TEXT_TO_KEY);

        if (handleKey == null) {
            handleKey = new Key();
        }


        if (!(handleKey instanceof Key)) {
            throw new IllegalArgumentException("不支持的Key类型:" + kz);
        }

        Key key = (Key) handleKey;

        //获取Key的所有分段
        List<Segment> list = key.getSegments();
        if (list.size() > 0) {

            if (!(obj instanceof JSON)) {
                throw new IllegalArgumentException("不支持对非JSON对象进行赋值操作");
            }

            //父级对象
            Object p = obj;

            //赋值器
            ValueSetter setter = null;

            for (int i = 0; i < list.size(); i++) {

                Segment segment = list.get(i);

                if (segment.type == SegmentType.NAME) {

                    String name = segment.name;

                    //如果父节点不存在. 初始化一个父节点的元素
                    if (p == null) {
                        p = new JSONObject();
                        setter.changeValue(p);
                    } else if (!(p instanceof JSONObject)) {
                        //检查是否是期望的类型
                        throw new UnsupportedOperationException("期望JSONObject,当前节点不支持赋值操作:" + key.subKey(0, i));
                    }

                    JSONObject z = (JSONObject) p;

                    //赋值器用来给 当前节点赋值
                    setter = new ObjectSetter(z, name);

                    //获取一下当前节点
                    p = z.get(name);

                } else if (segment.type == SegmentType.INDEX) {

                    int index = segment.index;

                    //如果父节点不存在. 初始化一个父节点的元素
                    if (p == null) {
                        p = new JSONArray();
                        setter.changeValue(p);
                    } else if (!(p instanceof JSONArray)) {
                        //检查是否是期望的类型
                        throw new UnsupportedOperationException("期望JSONArray,当前节点不支持赋值操作:" + key.subKey(0, i));
                    }

                    JSONArray z = (JSONArray) p;

                    //赋值器用来给 当前节点赋值
                    setter = new ArraySetter(z, index);


                    if (z.size() <= index) {
                        for (int j = -1; j < index; j++) {
                            z.add(null);
                        }
                    }

                    //获取一下当前节点
                    p = z.get(index);
                } else {
                    throw new UnsupportedOperationException("暂时不支持的分段类型:" + segment.type);
                }
            }

            setter.changeValue(value);

        }
    }


    //方法合并,设置并返回被修改的节点,返回值可用于链式编程
    public Analyzer set(Object key, Object value) {

        set(this.getSource(), key, value);

        return this;

    }

    //设置值为null
/*    public Analyzer setNull(Object key) {
        return set(key, null);
    }*/
//
//    public Analyzer addElement(Object obj) {
//        if (obj instanceof Analyzer) {
//            int size = size();
//            return set(size, ((Analyzer) obj).getSource());
//        } else {
//            int size = size();
//            return set(size, obj);
//        }
//    }


    //======移除值=======

    /**
     * 移除值
     * 如果移除的key为列表中的元素,会导致某些KEY失效
     *
     * @param obj
     * @return
     */
    public static Object remove(Object obj, Object kz) {
        Object handleKey = KeyUtils.handleKey(kz, KeyMode.TEXT_TO_KEY);

        if (handleKey == null) {
            handleKey = new Key();
        }

        if (!(handleKey instanceof Key)) {
            throw new IllegalArgumentException("不支持的Key类型:" + kz);
        }

        Key key = (Key) handleKey;

        //获取Key的所有分段
        List<Segment> list = key.getSegments();
        if (list.size() > 0) {

            if (!(obj instanceof JSON)) {
                throw new IllegalArgumentException("不支持对非JSON对象进行删除操作");
            }

            //父级对象
            Object p = obj;

            //赋值器
            ValueSetter setter = null;

            for (int i = 0; i < list.size(); i++) {

                Segment segment = list.get(i);

                if (segment.type == SegmentType.NAME) {

                    String name = segment.name;

                    //如果父节点不存在. 初始化一个父节点的元素
                    if (p == null) {
                        return null;
                    } else if (!(p instanceof JSONObject)) {
                        //检查是否是期望的类型
                        throw new UnsupportedOperationException("期望JSONObject,当前节点不支持删除操作:" + key.subKey(0, i));
                    }

                    JSONObject z = (JSONObject) p;

                    //赋值器用来给 当前节点赋值
                    setter = new ObjectSetter(z, name);

                    //获取一下当前节点
                    p = z.get(name);

                } else if (segment.type == SegmentType.INDEX) {

                    int index = segment.index;

                    //如果父节点不存在. 初始化一个父节点的元素
                    if (p == null) {
                        return null;
                    } else if (!(p instanceof JSONArray)) {
                        //检查是否是期望的类型
                        throw new UnsupportedOperationException("期望JSONArray,当前节点不支持删除操作:" + key.subKey(0, i));
                    }

                    JSONArray z = (JSONArray) p;

                    //赋值器用来给 当前节点赋值
                    setter = new ArraySetter(z, index);


                    if (z.size() <= index) {
                        for (int j = -1; j < index; j++) {
                            z.add(null);
                        }
                    }

                    //获取一下当前节点
                    p = z.get(index);
                } else {
                    throw new UnsupportedOperationException("暂时不支持的分段类型:" + segment.type);
                }
            }

            return setter.remove();

        }

        throw new UnsupportedOperationException("无法对根节点执行移除操作");

    }


    public Object remove(Object key) {
        return remove(getSource(), key);
    }

    //================过程抽象================


    /**
     * 深度访问对象
     * 完整遍历整个对象
     *
     * @param nodeKey 当前正在被访问的节点的key
     * @param no      当前正在被访问节点的对象
     * @param visitor
     * @return
     */
    private static void visit(Key nodeKey, AnalyzeValueNode no, BranchNode<AnalyzeValueNode> visitor, int currentDeep, VisitContext visitContext) {

        Object node = no.get();

        if (node instanceof Map) {
            Map j = (Map) node;
            for (Object o : j.entrySet()) {

                Map.Entry entry = (Map.Entry) o;
                if (!(entry.getKey() instanceof String)) {
                    continue;
                }

                String ek = (String) entry.getKey();

                Key key = nodeKey.childKey(entry.getKey());
                Object v = entry.getValue();

                AnalyzeValueNode currentNode = new AnalyzeValueNode();
                currentNode.setParent(no);
                currentNode.setKey(key);
                currentNode.setName(ek);
                currentNode.setIndex(null);
                currentNode.set(v);
                visitor.signDataEvent(new DataNodeEvent<>(currentNode));
                if (visitContext.controlFlag == 1) {
                    continue;
                } else if (visitContext.controlFlag == 2) {
                    return;
                }

                visit(key, currentNode, visitor, currentDeep + 1, visitContext);

            }

        } else if (node instanceof Collection) {
            Collection a = (Collection) node;
            Iterator iterator = a.iterator();
            int i = 0;
            while (iterator.hasNext()) {
                Object v = iterator.next();
                Key key = nodeKey.childKey(i);
                AnalyzeValueNode currentNode = new AnalyzeValueNode();
//
                currentNode.setParent(no);
                currentNode.setKey(key);
                currentNode.setName(null);
                currentNode.setIndex(i);
                currentNode.set(v);

                //首先访问当前节点
                visitor.signDataEvent(new DataNodeEvent<>(currentNode));
                if (visitContext.controlFlag == 1) {
                    continue;
                } else if (visitContext.controlFlag == 2) {
                    return;
                }

                //再深度访问剩余节点
                visit(key, currentNode, visitor, currentDeep + 1, visitContext);

                i++;
            }
        }
    }


    /**
     * 深度访问一个对象
     * 访问时需指定深度
     * 如果深度小于等于0,将全部访问
     *
     * @param object  //     * @param deep    访问深度
     * @param visitor
     */
    private static void visit(Object object, BranchNode<AnalyzeValueNode> visitor, VisitContext visitContext) {
        Key analyzeKey = new Key();
        AnalyzeValueNode currentNode = new AnalyzeValueNode();
        currentNode.setKey(new Key());
        currentNode.set(object);
        visitor.signDataEvent(new DataNodeEvent<>(currentNode));
        if (visitContext.controlFlag == 1 || visitContext.controlFlag == 2) {
            return;
        }

        visit(analyzeKey, currentNode, visitor, 1, visitContext);

    }


    /**
     * 深度访问当前对象
     * <p>
     * //     * @param deep
     * //     * @param visitor
     */

    public QueryLinkNode<AnalyzeValueNode> flow() {

        //创建一个流对象
        Flow flow = new Flow();

        return () -> new QueryLinkNodeResult<>(next -> {

            //创建一个数据源
            Branch<AnalyzeValueNode> branch = BranchFactory.createSelfExecuteBranch("datasource", "<from analyzer>", new AnalyzeValueNodeFactory());

            //由当前线程执行
            BranchNode<AnalyzeValueNode> queuedBranch = branch.getFirstNode();
            try {


                VisitContext visitContext = new VisitContext();
                visitContext.controlFlag = 0;

                StopNow[] stopNows = new StopNow[]{null};

                queuedBranch.getBranch().addListener(StopNow.class, e -> {
                    stopNows[0] = e;
                    visitContext.controlFlag = 2;

                });

                next.onNode(queuedBranch);

                Object batch = DefaultBatch.INSTANCE;

                //批开始事件
                queuedBranch.signDataEvent(new BatchStartEvent<>(batch));
                visit(Analyzer.this.getSource(), queuedBranch, visitContext);

                //批结束事件
                queuedBranch.signDataEvent(new BatchEndEvent<>(batch));

                if (stopNows[0] != null) {
                    flow.emit(new FlowEnd(stopNows[0].getMsg(), stopNows[0].getException()));
                } else {
                    flow.emit(new FlowEnd("执行成功", null));
                }


            } catch (Exception e) {
                //刷新完成后
                queuedBranch.flush(() -> {
                    flow.emit(new FlowEnd("执行失败", e));
                });
            }


        }, flow);

    }

    /**
     * 访问上下文
     */
    private static class VisitContext {
        /**
         * 控制标记
         * 0 正常节点,1 跳过节点,2 结束
         */
        private int controlFlag = 0;

    }

 /*   @Override
    public void visit(Visitor<ValueNode> visitor) {
        visit(this.getSource(), visitor);
    }*/

/*
    private VisitAble.NodeDeepVisitor<ValueNode> forEachNode;

    @Override
    public QueryLinkNode viewEachNode(VisitAble.NodeDeepVisitor<ValueNode> forEachNode) {
        this.forEachNode = forEachNode;
        return this;
    }
*/


    //==================键相关操作========================


    /**
     * 从一组分析键中提取json节点,参数2筛选json节点的最少元素个数
     *
     * @return
     */
 /*   private static void extractJsonNode(List<Key> all, int index, int segment, int length, List<Key> grab) {

        all = new ArrayList<>(all);

        all.orderWith(java.util.Comparator.comparingInt(Key::segmentLength));
        Key lastKey = null;

        int lastN = -1;

        while (true) {

            //所有符合的键
            List<Key> match = new ArrayList<>();

            Segment currentSegment = null;

            Key fetch = null;

            for (int i = index; i < all.length(); i++) {

                if (currentSegment == null) {
                    Key analyzeKey = all.getNode(i);
                    currentSegment = analyzeKey.segmentAt(segment);
                    if (currentSegment != null) {
                        match.addElement(analyzeKey);
                        fetch = analyzeKey.subKey(0, segment + 1);
                    }
                    all.remove(i);
                    i--;
                } else {
                    Key a = all.getNode(i);
                    Segment testSegment = a.segmentAt(segment);
                    if (testSegment.equals(currentSegment)) {
                        all.remove(i);
                        i--;
                        match.addElement(a);
                    } else {
                        extractJsonNode(all, i, segment, length, grab);
                    }
                }
            }

            int s = match.length();
            if (s == 0) {
                if (lastKey != null) {
                    grab.addElement(lastKey);
                }
                return;
            }

            //是否到给定长度
            if (s >= length) {

                if (lastKey != null && lastN != s) {
                    //接收结果
                    grab.addElement(lastKey);
                }

                lastN = match.length();
                lastKey = fetch;

            }

            all = match;

            segment++;
        }

    }*/


    /**
     * 从all中找出超出一定次数的节点
     * 例如:
     * all: a.b.c  a.b.d  a.c.f  a.w
     * paramNumber 作为公共节点最少出现的次数
     * 如果为 4 则 则返回a,因为a作为公共节点出现了4次
     * 如果为 2 则 返回a  a.b  因为a出现了4次超过2次,而a.b出现了2次
     * <p>
     * all         所有的key
     * paramNumber 公共节点在all中出现的次数
     */
/*
    public static List<Key> extractJsonNode(List<Key> all, int paramNumber) {

        if (all.length() == 0) {
            return new ArrayList<>(all);
        }

        if (paramNumber < 1) {
            throw new RuntimeException("无效size");
        }

        if (paramNumber == 1) {
            return new ArrayList<>(all);
        }

        List<Key> o = new ArrayList<>(all);
        List<Key> g = new ArrayList<>();
        extractJsonNode(o, 0, 0, paramNumber, g);

        //移除具有包含关系的

        return g;
    }
*/


    //=========格式化json==========
    private static String v(Object v) {
        if (v == null) {
            return "null";
        } else if (v instanceof String) {
            return "\"" + ((String) v).replace("\"", "\\\"").replace("\r", "\\r").replace("\n", "\\n") + "\"";
        } else {
            return v.toString();
        }
    }

    private static void deepString(Object object, StringBuilder builder, String tabLabel, int tab, boolean shouldTab) {

        //tab数量
        char[] chars = tabLabel.toCharArray();
        char[] cs = new char[tab * chars.length];
        for (int i = 0; i < tab; i++) {
            System.arraycopy(chars, 0, cs, i * chars.length, chars.length);
        }

        String t = new String(cs);
        if (object instanceof JSONObject) {
            if (shouldTab) {
                builder.append(t);
            }
            builder.append("{");
            JSONObject j = (JSONObject) object;

            Set<Map.Entry<String, Object>> entries = j.entrySet();

            List<Map.Entry<String, Object>> sortEts = new ArrayList<>(entries);

            sortEts.sort(Comparator.comparing(Map.Entry::getKey));

            Iterator<Map.Entry<String, Object>> iterator = sortEts.iterator();
            if (iterator.hasNext()) {
                Map.Entry<String, Object> entry = iterator.next();
                builder.append("\n");
                builder.append(t).append(tabLabel).append(v(entry.getKey())).append(": ");
                Object value = entry.getValue();
                if (!(value instanceof JSON)) {
                    builder.append(v(value));
                } else {
                    deepString(value, builder, tabLabel, tab + 1, false);
                }
                while (iterator.hasNext()) {
                    entry = iterator.next();
                    builder.append(",\n").append(t).append(tabLabel).append(v(entry.getKey())).append(": ");
                    value = entry.getValue();
                    if (!(value instanceof JSON)) {
                        builder.append(v(value));
                    } else {
                        deepString(value, builder, tabLabel, tab + 1, false);
                    }
                }
                builder.append("\n");
                builder.append(t);
            }
            builder.append("}");

        } else if (object instanceof JSONArray) {
            JSONArray a = (JSONArray) object;
            if (shouldTab) {
                builder.append(t);
            }
            builder.append("[");
            Iterator<Object> iterator = a.iterator();

            if (iterator.hasNext()) {
                builder.append("\n");
                Object next = iterator.next();
                if (!(next instanceof JSON)) {
                    builder.append(t).append(tabLabel).append(v(next));
                } else {
                    deepString(next, builder, tabLabel, tab + 1, true);
                }
                while (iterator.hasNext()) {
                    next = iterator.next();
                    builder.append(",\n");
                    if (!(next instanceof JSON)) {
                        builder.append(t).append(tabLabel).append(v(next));
                    } else {
                        deepString(next, builder, tabLabel, tab + 1, true);
                    }
                }
                builder.append("\n");
                builder.append(t);
            }
            builder.append("]");
        }
    }

    public String format(String tab) {
        return format(getSource(), tab);
    }

    public String format() {
        return format(getSource(), "\t");
    }

    public static String format(Object obj) {
        return format(obj, "\t");
    }

    public static String format(Object obj, String tab) {
        if (!(obj instanceof JSON)) {
            return v(obj);
        }
        StringBuilder builder = new StringBuilder();
        deepString(obj, builder, tab, 0, false);
        return builder.toString();
    }

    //===处理成json字符串====
    public String toJsonString() {
        Object content = this.getSource();
        if (content instanceof JSON) {
            return ((JSON) content).toJSONString();
        }
        throw new RuntimeException(content == null ? "null" : content.getClass() + "  不支持转json文本");
    }

    @Override
    public String toString() {
        Object content = getSource();
        if (content == null) {
            return null;
        }
        return content.toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Analyzer) {
            Object content = getSource();
            if (content == null) {
                return ((Analyzer) obj).getSource() == null;
            }
            return content.equals(((Analyzer) obj).getSource());
        }
        return false;
    }


    @Override
    public int hashCode() {
        Object content = getSource();
        if (content == null) {
            return 0;//空值的hash为0
        }
        return content.hashCode();
    }


 /*   public List<Analyzer> retrieve(Collection<Key> ks) {
        List<Analyzer> analyzers = new ArrayList<>();
        for (Key k : ks) {
            Analyzer analyzer = getAnalyzer(k);
            analyzers.addElement(analyzer);
        }
        return analyzers;
    }*/

    //====忽略掉顺序进行比较=====
/*
    public CompareResult compareOutOfOrder(Analyzer target) {
        return compareOutOfOrder(this, target);
    }

    public static CompareResult compareOutOfOrder(Analyzer source, Analyzer target) {
        Analyzer c1 = source.selfCopy();
        Analyzer c2 = target.selfCopy();

        c1.absoluteKey = new Key();
        c2.absoluteKey = new Key();
        List<Key> diffA2b = new ArrayList<>();
        List<Key> diffB2a = new ArrayList<>();
        boolean b = compareOutOfOrder(c1, c2, diffA2b, diffB2a);

        if (!b) {
            diffA2b.addElement(c1.absoluteKey);
            diffB2a.addElement(c2.absoluteKey);
        }


        diffA2b.sort(java.util.Comparator.comparing(Key::toString));

        diffB2a.sort((java.util.Comparator.comparing(Key::toString)));

        return new CompareResult(b, diffA2b, diffB2a);
    }

    private static List<Key> IGNORE_LIST = new LinkedList<Key>() {
        @Override
        public boolean addElement(Key key) {
            return false;
        }
    };
*/

/*
    private static boolean compareOutOfOrder(Analyzer a, Analyzer b, List<Key> diffA2b, List<Key> diffB2a) {

        ContentType aContentType = a.getSourceType();
        ContentType bContentType = b.getSourceType();

        if (aContentType != bContentType) {
            return false;
        }

        if (aContentType == ContentType.ARRAY) {
            List<Key> aks = a.keysWithLength(1);
            List<Key> bks = b.keysWithLength(1);
            if (aks.size() == 0) {
                return bks.size() == 0;
            }
            List<Analyzer> aas = a.retrieve(aks);
            List<Analyzer> bas = b.retrieve(bks);

            for (int i = 0; i < aas.size(); i++) {
                Analyzer aa = aas.get(i);
                for (int j = 0; j < bas.size(); j++) {
                    Analyzer ba = bas.get(j);
                    if (compareOutOfOrder(aa, ba, IGNORE_LIST, IGNORE_LIST)) {
                        aas.remove(i);
                        bas.remove(j);
                        i--;
                        break;
                    }
                }
            }

            //  aas 和 bas 剩余的即为差异

            if (aas.size() == 0 && bas.size() == 0) {
                return true;
            } else {
                for (Analyzer aa : aas) {
                    diffA2b.addElement(aa.absoluteKey);
                }
                for (Analyzer ba : bas) {
                    diffB2a.addElement(ba.absoluteKey);
                }
                return false;
            }

        } else if (aContentType == ContentType.OBJECT) {
            List<Key> aks = a.keysWithLength(1);
            List<Key> bks = b.keysWithLength(1);
            if (aks.size() == 0) {
                return bks.size() == 0;
            }
            Map<Key, Analyzer> aMap = new HashMap<>();
            Map<Key, Analyzer> bMap = new HashMap<>();

            for (Key ak : aks) {
                aMap.executeOne(ak, a.getAnalyzer(ak));
            }

            for (Key bk : bks) {
                bMap.executeOne(bk, b.getAnalyzer(bk));
            }

            Iterator<Key> iterator = aMap.keySet().iterator();
            while (iterator.hasNext()) {
                Key next = iterator.next();
                Analyzer av = aMap.get(next);
                Analyzer bv = bMap.get(next);
                if (bv != null && compareOutOfOrder(av, bv, diffA2b, diffB2a)) {
                    iterator.remove();
                    bMap.remove(next);
                }
            }

            // 收集二者差异集

            if (aMap.size() == 0 && bMap.size() == 0) {
                return true;
            } else {
                for (Analyzer valueNode : aMap.values()) {
                    diffA2b.addElement(valueNode.absoluteKey);
                }
                for (Analyzer valueNode : bMap.values()) {
                    diffB2a.addElement(valueNode.absoluteKey);
                }
                return false;
            }

        } else {
            return a.equals(b);
        }
    }

*/

    public Object getSource() {
        return source;
    }


   /* public List<Key> keysMatches(String regex, int deep) {
        return deep((holder) -> {
            if (holder.getLeft().toString().matches(regex)) {
                return holder.getLeft();
            } else {
                return null;
            }
        }, deep, 0, 0);
    }

    */

    /**
     * 搜索不符合指定模式的key
     * <p>
     * //     * @param regex
     * //     * @param deep
     *
     * @return
     *//*
    public List<Key> keysNotMatches(String regex, int deep) {
        return deep((holder) -> {
            if (!holder.getLeft().toString().matches(regex)) {
                return holder.getLeft();
            } else {
                return null;
            }
        }, deep, 0, 0);
    }


    //所有key
    public List<Key> allKey(int deep) {
        return deep(ValueNode::getLeft, deep, 0, 0);
    }


    public List<Key> keysWithLength(int length) {
        return deep((holder) -> {
            if (holder.getLeft().segmentLength() == length) {
                return holder.getLeft();
            }
            return null;
        }, length, 0, 0);
    }

    public List<Key> keysWithMaxLength(int length) {
        return deep((holder) -> {
            if (holder.getLeft().segmentLength() <= length) {
                return holder.getLeft();
            }
            return null;
        }, length, 0, 0);
    }
*/

}
